using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace TermitesMagnets
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Magnet : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private Boolean isEnabled;

        public Boolean IsEnabled
        {
            get { return isEnabled; }
            set { isEnabled = value; }
        }

        private GameplayScreen GameScreen;
        private int width;
        private int height;
        private static Texture2D texture;
        private static Texture2D texture1;
        private bool selected = false;
        private Level parent;
        private Color color;
        private int colorIndex;
        private Vector2 position;
        private BoundingSphere boundingSphere;
        private BoundingBox boundingBox;
        private Vector2 speed;
        private Texture2D textureSelected;
        private bool isAI = false;
        private AIPlayer ai;
        private Texture2D textureDisabled;

        internal AIPlayer Ai{ get { return ai; } set { ai = value; }}
        public bool IsAI{ get { return isAI; } set { isAI = value; } }
        public Level Parent{ get { return parent; }}
        public bool Selected{ get { return selected; } set { selected = value; }}
        public Color Color{ get { return color; } set { color = value; }}
        public int ColorIndex{ get { return colorIndex; } set { colorIndex = value; }}
        public Vector2 Position{ get { return position; } set { position = value; }}
        
        public Vector2 Speed{ get { return speed; } set { speed = value; }}

        public Magnet(Game game, Level parent, Vector2 position, Color color, int colorIndex)
            : base(game)
        {
            this.isEnabled = true;
            this.GameScreen = GameplayScreen.GlobalGame;
            this.parent = parent;
            this.ColorIndex = colorIndex;
            this.color = color;
            this.speed = new Vector2(0, 0);
            this.position = position;
            this.parent.AddComponent(this);
            this.ai = new AIPlayer(GameplayScreen.Difficulty);
        }

        public Magnet(Game game, Level parent, Vector2 position, Color color, int colorIndex, bool isAI)
            : this(game, parent, position, color, colorIndex)
        {
            this.isAI = isAI;
            if (!isAI)
                selected = true;
        }

        public static void LoadContent(ContentManager Content)
        {
            //texture = Content.Load<Texture2D>(@"Images\magnet");
            //textureSelected = Content.Load<Texture2D>(@"Images\magnet_selected");
            //textureDisabled = Content.Load<Texture2D>(@"Images\magnet_disabled");
            texture1 = Content.Load<Texture2D>(@"Images\Magnets");
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here
            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            if (GameScreen.IsActive)
            {
                float timeDiff = (float)gameTime.ElapsedGameTime.TotalSeconds;
                MouseState mouse = Mouse.GetState();
                KeyboardState keyState = Keyboard.GetState();
                if (this.selected)
                {
                    Vector2 diff = new Vector2(0, 0);
                    if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
                    {
                        diff += new Vector2(0, -1);
                    }
                    if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S))
                    {
                        diff += new Vector2(0, 1);
                    }
                    if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
                    {
                        diff += new Vector2(-1, 0);
                    }
                    if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
                    {
                        diff += new Vector2(1, 0);
                    }
                    if (keyState.IsKeyDown(Keys.LeftControl) || keyState.IsKeyDown(Keys.RightControl))
                        this.speed = new Vector2(0, 0);
                    this.Speed += diff * GameScreen.GameSpeed;
                }
                if (mouse.LeftButton == ButtonState.Pressed && this.selected)
                {
                    Vector2 clickLocation = GameScreen.CurrentLevel.Board.RealPositionToWorld(new Vector2(mouse.X, mouse.Y));
                    Vector2 diff = clickLocation - this.Position;
                    Vector2 speedDiff = diff / diff.Length();
                    this.Speed += speedDiff * GameScreen.GameSpeed;
                }
                else
                {
                    this.Speed = this.Speed - this.Speed * timeDiff;
                }

                if (mouse.RightButton == ButtonState.Pressed && this.selected)
                {
                    this.Speed = new Vector2(0, 0);
                }

                if (GameScreen.CurrentLevel.Magnets.Contains(this))
                {
                    this.Position += this.Speed * timeDiff;
                    // If the magnet position is outside of the world box -> bounce it back
                    if (!GameScreen.CurrentLevel.Board.IsInWorld(this.Position))
                    {
                        while (!GameScreen.CurrentLevel.Board.IsInWorld(this.Position))
                        {
                            this.Position -= this.Speed * timeDiff;
                        }
                        this.Speed = -(this.speed / 2);
                    }
                }

                if (IsAI)
                {
                    Ai.doCommand(gameTime);
                }
            }
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            GameScreen.SpriteBatch.Begin();
            Texture2D current;
            if (isEnabled)
            {
                if (selected)
                    current = textureSelected;
                else
                    current = texture;
            }
            else
            {
                current = textureDisabled;
            }
            Vector2 worldPosition = GameScreen.CurrentLevel.Board.WorldPositionToReal(position);
            Rectangle destRect = new Rectangle((int)worldPosition.X,(int)worldPosition.Y,width,height);
            Vector2 origin = new Vector2(width/2,height/2);
            GameScreen.SpriteBatch.Draw(texture1,
                      destRect,
                      calculateOriginRectangle(color),
                      color,
                      0, // rotation
                      origin,
                      SpriteEffects.None,
                      0);
            GameScreen.SpriteBatch.End();
            base.Draw(gameTime);
        }

        public virtual void Interact(Termite termite, float timeDiff)
        {
            if (isEnabled)
            {
                Boolean inOtherHome = false;
                foreach (TargetRect tar in parent.Targets)
                {
                    if ( (tar.ColorIndex != colorIndex) && 
                         (tar.Rectangle.Intersects(
                            new Rectangle((int)position.X, (int)position.Y, 1, 1))
                            ) 
                        )
                    {
                        inOtherHome = true;
                    }

                }

                Vector2 diff = this.Position - termite.Position;
                int distance = (int)diff.LengthSquared();
                if (this.ColorIndex == termite.ColorIndex)
                {
                    if (distance < 15625)
                    {
                        termite.Speed += diff / distance * timeDiff * 1000 * GameScreen.GameSpeed;
                    }
                }
                else
                {
                    if ((inOtherHome) && (distance < 15625))
                        termite.Speed -= diff / distance * timeDiff * 6000 * 2 * GameScreen.GameSpeed;
                    else if (distance < 2500)
                        termite.Speed -= diff / distance * timeDiff * 1333 * GameScreen.GameSpeed;
                }
            }
        }

        public Rectangle calculateOriginRectangle(Color color)
        {
            Rectangle source = new Rectangle();

            if (color.Equals(Color.IndianRed) && isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 1;
                source.Y = 14;
            }
            else if (color.Equals(Color.IndianRed) && !isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 1;
                source.Y = 38;
            }
            
            else if (color.Equals(Color.LightBlue) && isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 32;
                source.Y = 14;
            }
            else if (color.Equals(Color.LightBlue) && !isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 31;
                source.Y = 38;
            }

            if (color.Equals(Color.LightGreen) && isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 61;
                source.Y = 14;
            }
            else if (color.Equals(Color.LightGreen) && !isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 60;
                source.Y = 38;
            }

            if (color.Equals(Color.LightYellow) && isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 91;
                source.Y = 14;
            }
            else if (color.Equals(Color.LightYellow) && !isEnabled)
            {
                source.Width = 21; width = 21;
                source.Height = 21; height = 21;
                source.X = 90;
                source.Y = 38;
            }
            return source;
        }
    }
}
